﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Bazookabird.Wpf.Model;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Bazookabird.Wpf.Queries
{
    // TODO: Cleanup, copied code
    public static class QueryHelper
    {
        public static List<WorkItemNode> FilterTasks(IEnumerable<WorkItemNode> workItemCollection, string workItemType, string state)
        {
            var workItems = workItemCollection
                .Where(w => w.WorkItem.Type.Name == workItemType)
                .Where(w => w.WorkItem.State == state)
                .ToList();
            return workItems;
        }

        public static List<WorkItemNode> FetchItems(WorkItemStore workItemStore, QueryDefinition queryDefinition)
        {
            var query = new Query(workItemStore, queryDefinition.QueryText,
                GetParamsDictionary(queryDefinition.Project.Name, ResolveCurrentUserDisplayName(workItemStore)));
            return RunQuery(workItemStore, queryDefinition, query);
        }

        public static List<WorkItemNode> RunQuery(WorkItemStore workItemStore, QueryDefinition queryDef, Query query)
        {
            // get the query

            // get the link types
            var linkTypes = new List<WorkItemLinkType>(workItemStore.WorkItemLinkTypes);

            // run the query
            var list = new List<WorkItemNode>();
            if (queryDef.QueryType == QueryType.List)
            {
                foreach (WorkItem wi in query.RunQuery())
                {
                    list.Add(new WorkItemNode { WorkItem = wi, RelationshipToParent = "" });
                }
            }
            else
            {
                var workItemLinks = query.RunLinkQuery().ToList();
                list = WalkLinks(workItemStore, workItemLinks, linkTypes, null);
            }

            return list;
        }

        private static List<WorkItemNode> WalkLinks(WorkItemStore workItemStore, IEnumerable<WorkItemLinkInfo> workItemLinks, IEnumerable<WorkItemLinkType> linkTypes, WorkItemNode current)
        {            
            var currentId = 0;
            if (current != null)
            {
                currentId = current.WorkItem.Id;
            }

            if (workItemLinks == null) throw new NotImplementedException();
            {
                var workitemLinksList = workItemLinks.ToList();
                var workItems = (from linkInfo in workitemLinksList
                                 where linkInfo.SourceId == currentId
                                 select new WorkItemNode
                                            {
                                                WorkItem = workItemStore.GetWorkItem(linkInfo.TargetId),
                                                RelationshipToParent = linkInfo.LinkTypeId == 0
                                                                           ? "Parent"
                                                                           : linkTypes.Single(
                                                                               lt =>
                                                                               lt.ForwardEnd.Id ==
                                                                               linkInfo.LinkTypeId).ForwardEnd.Name
                                            }).ToList();
                workItems.ForEach(w => w.Children = WalkLinks(workItemStore, workitemLinksList, linkTypes, w));
                return workItems;
            }
        }

        public static string ResolveCurrentUserDisplayName(WorkItemStore workItemStore)
        {
            var securityService = workItemStore.TeamProjectCollection.GetService<IGroupSecurityService>();
            var accountName = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName);
            var memberInfo = securityService.ReadIdentity(SearchFactor.AccountName, accountName, QueryMembership.None);

            return memberInfo != null ? memberInfo.DisplayName : Environment.UserName;
        }

        public static IDictionary GetParamsDictionary(string teamProjectName, string currentUserDisplayName)
        {
            return new Dictionary<string, string>
                       {
                           {"project", teamProjectName},
                           {"me", currentUserDisplayName}
                       };
        }
    }
}
